package com.ep.thirdPlatformProject.oa.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ep.thirdPlatformProject.dhg.entity.DhgEmployeeEntity;
import com.ep.thirdPlatformProject.dhg.entity.vo.DhgDepartmentVO;
import com.ep.thirdPlatformProject.dhg.service.DhgDepartmentService;
import com.ep.thirdPlatformProject.oa.entity.vo.OAOrgChangeVO;
import com.ep.thirdPlatformProject.oa.service.OACompanyService;
import com.ep.thirdPlatformProject.oa.service.OADepartmentService;
import com.ep.thirdPlatformProject.system.config.oa.WorkflowFormProperties;
import com.ep.thirdPlatformProject.oa.entity.OAUserEntity;
import com.ep.thirdPlatformProject.oa.service.HrmResourceService;
import com.ep.thirdPlatformProject.oa.util.OAHrmTemplateUtil;
import com.ep.thirdPlatformProject.system.util.CaffeineCacheUtils;
import com.xxl.job.core.context.XxlJobHelper;
import localhost.services.HrmService.HrmServiceHttpBindingStub;
import localhost.services.HrmService.HrmServiceLocator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import weaver.hrm.webservice.DepartmentBean;
import weaver.hrm.webservice.JobTitleBean;
import weaver.hrm.webservice.SubCompanyBean;
import weaver.hrm.webservice.UserBean;


import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

/**
 * HRM资源服务impl
 *
 * @author Karl
 * @date 2024/05/28
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class HrmResourceServiceImpl implements HrmResourceService {

    private final WorkflowFormProperties workflowFormProperties;

    private final DhgDepartmentService dhgDepartmentService;

    private final OADepartmentService oaDepartmentService;

    private final OACompanyService oaCompanyService;


    private static final String JOB_TITLE_STR = "jobTitleList";

    private static final String SUB_COMPANY_STR = "subCompanyList";

    private static final String DEPARTMENT_STR = "departmentList";
    /**
     * 服务定位器
     */
    private final HrmServiceLocator serviceLocator = new HrmServiceLocator();


    /**
     * 获取人力资源管理岗位名称
     *
     * @param code code
     * @return {@link String }
     */
    @Override
    public String getHrmServiceJobTitleIdByCode(String code) {
        JobTitleBean[] hrmJobTitleInfo;
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            JobTitleBean[] obj = (JobTitleBean[]) CaffeineCacheUtils.getSync(JOB_TITLE_STR);
            if (ObjectUtil.isNull(obj)) {
                hrmJobTitleInfo = stub.getHrmJobTitleInfo("", "", "");
                CaffeineCacheUtils.putSync(JOB_TITLE_STR, hrmJobTitleInfo);
            } else {
                hrmJobTitleInfo = obj;
            }
            return Arrays.stream(hrmJobTitleInfo).filter(item -> Objects.equals(item.get_code(), code))
                    .findFirst().orElseThrow(() -> new RuntimeException("未能匹配到正确的岗位id")).get_jobtitleid();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }

    /**
     * 通过代码获取人力资源管理服务sum公司
     *
     * @param code 代码
     * @return {@link String }
     */
    @Override
    public String getHrmServiceSubCompanyByCode(String code) {
        SubCompanyBean[] companyBeans;
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            SubCompanyBean[] obj = (SubCompanyBean[]) CaffeineCacheUtils.getSync(SUB_COMPANY_STR);
            if (ObjectUtil.isNull(obj)) {
                companyBeans = stub.getHrmSubcompanyInfo("");
                CaffeineCacheUtils.putSync(SUB_COMPANY_STR, companyBeans);
            } else {
                companyBeans = obj;
            }
            return Arrays.stream(companyBeans).filter(item -> Objects.equals(item.get_code(), code))
                    .findFirst().orElseThrow(() -> new RuntimeException("未能正确匹配对应的公司")).get_subcompanyid();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }

    /**
     * 通过代码获取HRM服务部门
     *
     * @param code 代码
     * @return {@link String }
     */
    @Override
    public String getHrmServiceDepartmentByCode(String code) {
        DepartmentBean[] departmentBeans;
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            DepartmentBean[] obj = (DepartmentBean[]) CaffeineCacheUtils.getSync(DEPARTMENT_STR);
            if (ObjectUtil.isNull(obj)) {
                departmentBeans = stub.getHrmDepartmentInfo("", "");
                CaffeineCacheUtils.putSync(DEPARTMENT_STR, departmentBeans);
            } else {
                departmentBeans = obj;
            }
            return Arrays.stream(departmentBeans).filter(item -> Objects.equals(item.get_code(), code))
                    .findFirst().orElseThrow(() -> new RuntimeException("未能正确匹配对应的部门")).get_departmentid();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }

    @Override
    public UserBean getHrmServiceEmpInfoByCode(String code) {
        try {
            // 验证创建人工号不能为空，否则流程无法完成
            Opt.ofNullable(code).orElseThrow(() -> new RuntimeException("创建人的工号不能为空"));
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);

            UserBean[] hrmUserInfo = stub.getHrmUserInfo("", code, "", "", "", "");

            if (hrmUserInfo.length == 0) {
                return null;
            }
            return hrmUserInfo[0];
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }

    @Override
    public SubCompanyBean[] getAllSubCompanyList() {
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            return stub.getHrmSubcompanyInfo("");

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("查询错误：" + e.getMessage(), e);
        }
    }

    @Override
    public DepartmentBean[] getAllDepartmentList() {
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            return stub.getHrmDepartmentInfo("", "");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("查询错误：" + e.getMessage(), e);
        }
    }

    @Override
    public UserBean[] getAllEmpInfo() {
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);

            return stub.getHrmUserInfo("", "", "", "", "", "");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }

    @Override
    public String syncHrmResource(OAUserEntity entity) {
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);

            // 组装出完整的xml格式对象参数
            String beanXml = OAHrmTemplateUtil.parseEntityXml(entity, "hrm");
            String fullXml = OAHrmTemplateUtil.getHrmUserinfoTemplateStr(beanXml);

            String res = stub.synHrmResource("", fullXml);

            return OAHrmTemplateUtil.parseResponseXml(res);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误,当前操作为：" + entity.action() + ",错误原因:" + e.getMessage(), e);
        }
    }

    @Override
    public UserBean firstSaveOAUser(DhgEmployeeEntity entity) {
        try {
            // 查看员工是否存在
            UserBean oaUser = getHrmServiceEmpInfoByCode(entity.getEmpNo());
            if (ObjectUtil.isNotNull(oaUser)) {
                XxlJobHelper.log("员工OA中存在，不需要新建");
                return oaUser;
            }
            // 不存在就开始保存数据
            XxlJobHelper.log("员工OA中不存在，开始新建");
            // 获取三级部门名称
            String thirdLevePathName = compareFullPathByCode(entity.getOrgCode());

            // 转换数据开始 (后期通过mapstruct赋值)
            OAUserEntity oaUserEntity = new OAUserEntity()
                    .action(OAHrmTemplateUtil.ADD)
                    .sex(entity.getSex())
                    .lastname(entity.getEmpName())
                    .workcode(entity.getEmpNo())
                    .subcompany(entity.getCompanyName())
                    // 部门全路径
                    .department(thirdLevePathName)
                    .jobtitle(entity.getPostName())
                    .jobgroupid("其他")
                    .jobactivityid("其他")
                    .locationid("")
                    .mobile(entity.getMobile())
                    .workroom(entity.getWorkPlace())
                    .managerid(entity.getLeaderEmpNo())
                    .seclevel("0");
            // 新增逻辑，判断组织变更是否会影响，需要人工处理
            // findCodeInChangeOrgList(entity.getOrgCode(),oaUserEntity);
            // 同步到oa用户表里去
            String res = syncHrmResource(oaUserEntity);
            log.info("同步结果为：{}", res);
            UserBean afterEntity = getHrmServiceEmpInfoByCode(entity.getEmpNo());
            log.info("反查数据库的结果为：{}", afterEntity);
            return afterEntity;

        } catch (Exception e) {
            log.error("第一步保存员工信息错误:{}", e.getMessage(), e);
            throw new RuntimeException("第一步保存员工信息错误：" + e.getMessage(), e);
        }
    }

    @Override
    public String syncHrmCompany(String fullXmlStr) {
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            String res = stub.synSubCompany("", fullXmlStr);
            return OAHrmTemplateUtil.parseResponseXml(res);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }

    @Override
    public String syncDepartment(String fullXmlStr) {
        try {
            HrmServiceHttpBindingStub stub = new HrmServiceHttpBindingStub(new URL(workflowFormProperties.getHrmResourceUrl()), serviceLocator);
            String res = stub.synDepartment("", fullXmlStr);
            return OAHrmTemplateUtil.parseResponseXml(res);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("提交错误：" + e.getMessage(), e);
        }
    }


    /**
     * 在变更组织列表中找到代码信息
     *
     * @param orgCode      组织代码
     * @param oaUserEntity Oa用户实体
     */
    @Deprecated
    public void findCodeInChangeOrgList(String orgCode, OAUserEntity oaUserEntity) {
        StringBuilder sb = new StringBuilder();
        List<OAOrgChangeVO> changeDepartmentList = oaDepartmentService.getDepartmentChangeList();
        List<OAOrgChangeVO> changeCompanyList = oaCompanyService.getChangeCompanyList();

        List<OAOrgChangeVO> all = Stream.concat(changeDepartmentList.stream(), changeCompanyList.stream()).toList();

        all.stream().filter(item ->
                item.getOrgCode() != null
                        && item.getOrgCode().equals(orgCode)
        ).findFirst().ifPresent(orgVo ->
                sb.append("请谨慎处理此人员新增操作!\n\r当前人所在的")
                        .append(orgVo.getLevel() == 1 ? "组织" : "部门")
                        .append("| id:").append(orgVo.getId()).append(",")
                        .append("名称:").append(orgVo.getOrgName()).append(",")
                        .append("编号:").append(orgVo.getOrgCode())
                        .append(" | 已经被修改过了")
                        .append("\n\r")
                        .append("修改时间:").append(DateUtil.date(orgVo.getModifiedTime())).append(",")
                        .append("修改人:").append(orgVo.getModifyUsername()).append(",")
                        .append("修改人工号:").append(orgVo.getModifyUserNo())
                        .append("\n\r")
                        .append("新增员工基础信息：").append(oaUserEntity.toString())

        );
        if (!sb.toString().isEmpty()) {
            throw new RuntimeException(sb.toString());
        }

    }

    /**
     * 按代码比较部门完整路径，如果异常就抛出异常并且发送邮件
     *
     * @param deptCode 部门代码
     * @return 如果无误，返回部门全路径
     */
    @Override
    public String compareFullPathByCode(String deptCode) {
        // 部门名称需要传递全路径
        DhgDepartmentVO department = dhgDepartmentService.getDepartmentTreeByCode(deptCode);
        // 获取三级部门名称
        String thirdLevePathName = department.getTargetPathName();

        if (StrUtil.isEmpty(thirdLevePathName)) {
            throw new RuntimeException("三级部门以上名称为空，请检查部门全路径！");
        }
        // OA上的部门名称全路径
        String fullPath = oaDepartmentService.getOADeptFullPathNameByCode(deptCode);

        if (StrUtil.isEmpty(fullPath)) {
            throw new RuntimeException("OA部门全路径为空，请检查部门全路径！");
        }
        // 由于东宝部门取的不带公司，所以需要截取第一个'>' 后的所有数据
        fullPath = fullPath.substring(fullPath.indexOf(">") + 1);
        if (fullPath.equals(thirdLevePathName)) {
            return thirdLevePathName;
        } else {
            throw new RuntimeException(StrUtil.format("""
                    {}：出现了东宝oa全路径不匹配的情况，请检查后在处理！
                    东宝：{}
                    OA: {}
                    """, deptCode, thirdLevePathName, fullPath));
        }


    }


}
